home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Atlanta_1990 / Atlanta-Devcon.2 / Libraries / IFFParse / Examples / sift.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-26  |  5.4 KB  |  250 lines

  1. /*  :ts=8 bk=0
  2.  *
  3.  * sift.c:    Takes any IFF file and tells you what's in it.  Verifies
  4.  *        syntax and all that cool stuff.
  5.  *
  6.  * Usage: sift -c        ; For clipboard scanning
  7.  *    or  sift <file>        ; For DOS file scanning
  8.  *
  9.  * Reads the specified stream and prints an IFFCheck-like listing of the
  10.  * contents of the IFF file, if any.  Stream is a DOS file for <file>
  11.  * argument, or is the clipboard's primary clip for -c.
  12.  * This program must be run from a CLI.
  13.  *
  14.  * Stuart Ferguson                    8807.??
  15.  * Leo L. Schwab (adjusted for new semantics)        8808.16
  16.  * shf (adjusted some more, added clipboard)        8809.01
  17.  * ewhac (more adjusting around)            8811.02
  18.  * shf (adjusted for Dec 88 semantics)            8812.18
  19.  * ewhac (severe commenting)                8902.23
  20.  * ewhac (update to 1.4 Beta)                8912.06
  21.  * ewhac (Latticeification)                9005.23
  22.  */
  23. #include <exec/types.h>
  24. #include <libraries/dosextens.h>
  25. #include <libraries/iffparse.h>
  26. #include <clib/exec_protos.h>
  27. #include <clib/dos_protos.h>
  28. #include "iffparse_protos.h"
  29. #include "iffparse.p"
  30.  
  31.  
  32. /*
  33.  * Forward function declarations.  (I hate ANSI.)
  34.  */
  35. void    PrintTopChunk (struct IFFHandle *);
  36.  
  37.  
  38. /*
  39.  * English error messages for possible IFFERR_#? returns from various
  40.  * IFF routines.  To get the index into this array, take your IFFERR code,
  41.  * negate it, and subtract one.
  42.  *  idx = -error - 1;
  43.  */
  44. char    *errormsgs[] = {
  45.     "End of file (not an error).",
  46.     "End of context (not an error).",
  47.     "No lexical scope.",
  48.     "Insufficient memory.",
  49.     "Stream read error.",
  50.     "Stream write error.",
  51.     "Stream seek error.",
  52.     "File is corrupt.",
  53.     "IFF syntax error.",
  54.     "Not an IFF file.",
  55.     "Required call-back hook missing.",
  56.     "Return to client.  You should never see this."
  57. };
  58.  
  59. struct Library *IFFParseBase;
  60.  
  61.  
  62. main (argc, argv)
  63. int    argc;
  64. char    **argv;
  65. {
  66.     struct IFFHandle    *iff = NULL;
  67.     long            error;
  68.     short            cbio;
  69.  
  70.     /*
  71.      * Check to see if an filename argument was passed.
  72.      */
  73.     if (argc < 2) {
  74.         printf ("usage: %s <file | \"-c\">\n", argv[0]);
  75.         goto die;
  76.     }
  77.  
  78.     /*
  79.      * Check to see if were doing I/O to the Clipboard.
  80.      */
  81.     cbio = (argv[1][0] == '-'  &&  argv[1][1] == 'c');
  82.  
  83.     if (!(IFFParseBase = OpenLibrary ("iffparse.library", 0L))) {
  84.         puts ("Can't open iff parsing library.");
  85.         goto die;
  86.     }
  87.  
  88.     /*
  89.      * Allocate IFF_File structure.
  90.      */
  91.     if (!(iff = AllocIFF ())) {
  92.         puts ("AllocIFF() failed.");
  93.         goto die;
  94.     }
  95.  
  96.     /*
  97.      * Internal support is provided for both AmigaDOS files, and the
  98.      * clipboard.device.  This bizarre 'if' statement performs the
  99.      * appropriate machinations for each case.
  100.      */
  101.     if (cbio) {
  102.         /*
  103.          * Set up IFF_File for Clipboard I/O.
  104.          */
  105.         if (!(iff->iff_Stream =
  106.                 (ULONG) OpenClipboard (PRIMARY_CLIP)))
  107.         {
  108.             puts ("Clipboard open failed.");
  109.             goto die;
  110.         }
  111.         InitIFFasClip (iff);
  112.     } else {
  113.         /*
  114.          * Set up IFF_File for AmigaDOS I/O.
  115.          */
  116.         if (!(iff->iff_Stream = Open (argv[1], MODE_OLDFILE))) {
  117.             puts ("File open failed.");
  118.             goto die;
  119.         }
  120.         InitIFFasDOS (iff);
  121.     }
  122.  
  123.     /*
  124.      * Start the IFF transaction.
  125.      */
  126.     if (error = OpenIFF (iff, IFFF_READ)) {
  127.         puts ("OpenIFF failed.");
  128.         goto die;
  129.     }
  130.  
  131.     while (1) {
  132.         /*
  133.          * The interesting bit.  IFFPARSE_RAWSTEP permits us to
  134.          * have precision monitoring of the parsing process, which
  135.          * is necessary if we wish to print the structure of an
  136.          * IFF file.  ParseIFF() with _RAWSTEP will return the
  137.          * following things for the following reasons:
  138.          *
  139.          * Return code:            Reason:
  140.          * 0                Entered new context.
  141.          * IFFERR_EOC            About to leave a context.
  142.          * IFFERR_EOF            Encountered end-of-file.
  143.          * <anything else>        A parsing error.
  144.          */
  145.         error = ParseIFF (iff, IFFPARSE_RAWSTEP);
  146.  
  147.         /*
  148.          * Since we're only interested in when we enter a context,
  149.          * we "discard" end-of-context (_EOC) events.
  150.          */
  151.         if (error == IFFERR_EOC)
  152.             continue;
  153.         else if (error)
  154.             /*
  155.              * Leave the loop if there is any other error.
  156.              */
  157.             break;
  158.  
  159.         /*
  160.          * If we get here, error was zero.
  161.          * Print out the current state of affairs.
  162.          */
  163.         PrintTopChunk (iff);
  164.     }
  165.  
  166.     /*
  167.      * If error was IFFERR_EOF, then the parser encountered the end of
  168.      * the file without problems.  Otherwise, we print a diagnostic.
  169.      */
  170.     if (error == IFFERR_EOF)
  171.         puts ("File scan complete.");
  172.     else
  173.         printf ("File scan aborted, error %ld: %s\n",
  174.             error, errormsgs[-error - 1]);
  175.  
  176. die:
  177.     if (iff) {
  178.         /*
  179.          * Terminate the IFF transaction with the stream.  Free
  180.          * all associated structures.
  181.          */
  182.         CloseIFF (iff);
  183.  
  184.         /*
  185.          * Close the stream itself.
  186.          */
  187.         if (iff->iff_Stream)
  188.             if (cbio)
  189.                 CloseClipboard ((struct ClipboardHandle *)
  190.                         iff->iff_Stream);
  191.             else
  192.                 Close (iff->iff_Stream);
  193.  
  194.         /*
  195.          * Free the IFF_File structure itself.
  196.          */
  197.         FreeIFF (iff);
  198.     }
  199.     if (IFFParseBase)    CloseLibrary (IFFParseBase);
  200.  
  201.     return (0);
  202. }
  203.  
  204.  
  205. void
  206. PrintTopChunk (iff)
  207. struct IFFHandle *iff;
  208. {
  209.     struct ContextNode    *top;
  210.     short            i;
  211.     char            idbuf[5];
  212.  
  213.     /*
  214.      * Get a pointer to the context node describing the current context.
  215.      */
  216.     if (!(top = CurrentChunk (iff)))
  217.         return;
  218.  
  219.     /*
  220.      * Print a series of dots equivalent to the current nesting depth of
  221.      * chunks processed so far.  This will cause nested chunks to be
  222.      * printed out indented.
  223.      */
  224.     for (i = iff->iff_Depth;  i--; )
  225.         printf (". ");
  226.  
  227.     /*
  228.      * Print out the current chunk's ID and size.
  229.      */
  230.     printf ("%s %ld ", IDtoStr (top->cn_ID, idbuf), top->cn_Size);
  231.  
  232.     /*
  233.      * Print the current chunk's type, with a newline.
  234.      */
  235.     puts (IDtoStr (top->cn_Type, idbuf));
  236. }
  237.  
  238. /*
  239.  * Disable Lattice default ^C trap.
  240.  */
  241. chkabort ()
  242. {
  243.     return (0);
  244. }
  245.  
  246. CXBRK ()
  247. {
  248.     return (0);
  249. }
  250.